/*
 * Copyright 2011 Digia Oyj - Pasi Hirvonen <pasi.hirvonen@digia.fi>
 *
 * Requests to the remote server produce XmlRpcResponses. The response
 * includes a parsed return value from the methodCall, or a failure.
 *
 * If no failure occurred, returnValue is a QVariant()  that can be a list,
 * map or a single value. The lists and maps can contain further lists and
 * maps, etc.
 *
 * If the query was sent to the remote server successfully and a response
 * was received, but was an XML-RPC fault, error() will returns RpcFaultError
 * and errorCode() and errorString() will return the XML-RPC fault info.
 */

#ifndef TRACRPCRESPONSE_H
#define TRACRPCRESPONSE_H

#include <QtCore/QObject>

namespace XmlRpc {

class XmlRpcResponsePrivate;

class XmlRpcResponse : public QObject
{
    Q_OBJECT
    Q_ENUMS(XmlRpcError)
public:
    enum XmlRpcError {
        NoError = 0,
        NotConnectedError,
        NetworkError,
        XmlError,
        RpcFaultError /* i.e. xmlrpc call returned a fault. */
    };

    virtual ~XmlRpcResponse();

    // error() returns NoError if there were no errors during the call.
    // For error() values other than RpcFaultError, erroCode() and errorString() return
    // library specific codes. If the error is an XML-RPC fault, error() returns
    // RpcFaultError and the error code and string are set accordingly.
    XmlRpcError error() const;
    int errorCode() const;
    QString errorString() const;

    bool isFinished() const;

    QString methodCalled() const;
    QVariant returnValue() const;

    QString rawResponse() const;
signals:
    // response is a pointer-to-self. Use deleteLater().
    void finished(XmlRpcResponse *response);

protected:
    // TODO: rename publish
    explicit XmlRpcResponse(const QString &methodCalled, bool publish = true);
    /* errorCode is the XmlRpc error code, aka fault code and error string the
       corresponding error string or an implementation set error. error is for
       internal use here. */
    void setError(XmlRpcError error, int errorCode = 0, const QString &errorString = "");
    void setReturnValue(const QVariant &value);
    void parseResponse(const QString &content);
    /* Used by propagation */
    bool publish() const;

protected slots:
    void done();

private:
    void setRawResponse(const QString &text);

    friend class XmlRpcConnection;
    friend class XmlRpcConnectionPrivate;
    Q_DISABLE_COPY(XmlRpcResponse); // For now
    XmlRpcResponsePrivate *d;
};

} // namespace XmlRpc

#endif // TRACRPCRESPONSE_H
